package org.vacoor.xqq.ui.util;

/**
 * Created with IntelliJ IDEA.
 * User: vacoor
 * Date: 13-10-5
 * Time: 上午4:17
 * To change this template use File | Settings | File Templates.
 */

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

/**
 * 移动实现:
 * 1. 按下鼠标, 记录鼠标屏幕坐标为上一次坐标, 拖拽时记录拖拽鼠标屏幕坐标, 求出移动距离,并重置上一次坐标为当前坐标 窗口坐标 = 当前拖拽鼠标屏幕坐标+移动距离
 * 该方式由于 鼠标移动快时会产生误差, 造成鼠标明显漂移
 * <p/>
 * 2. 按下鼠标, 记录鼠标相对窗口坐标, 拖拽时记录拖拽坐标, 当前窗口坐标 = 当前拖拽鼠标屏幕坐标 - 相对窗口坐标
 * 该方式不用频繁重置坐标, 仅在按下时记录相对坐标, 始终相对窗口坐标不变, 因此不会漂移
 *
 * @author Vacoor
 */
public class WindowMoveHandler extends MouseAdapter {

    private Point relativePoint = new Point(-1, -1);
    private Component component;
    private Window window;

    public void bindWindowMoveHanderTo(Component component) {
        if (this.component != null) {
            this.component.removeMouseListener(this);
            this.component.removeMouseMotionListener(this);
        }
        this.component = component;

        this.window = getComponentWindow(component);
        component.addMouseListener(this);
        component.addMouseMotionListener(this);
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        // 非常态化拖动, 将不能恢复
        if ( window instanceof Frame && ( Frame.NORMAL != ((Frame) window).getExtendedState() ) ){
            return;
        }
        //window move
        Point dragPoint = e.getLocationOnScreen();
//        Point locationPoint = window.getLocationOnScreen();

        int x = dragPoint.x - relativePoint.x;
        int y = dragPoint.y - relativePoint.y;
//        Component window = SwingUtilities.getRoot(component);
        //window.setLocationRelativeTo(null);  这个不要设置, 会导致定位到中心, 在 win 下效果明显
        window.setLocation(x, y);
    }

    @Override
    public void mousePressed(MouseEvent e) {
        if (window == null) {
            window = getComponentWindow(component);
        }
        //window move
        relativePoint.move(e.getXOnScreen() - window.getX(), e.getYOnScreen() - window.getY());
    }

    static Window getComponentWindow(Component c) {
        Window win;
        if (c instanceof Window) {
            win = (Window) c;
        } else {
            win = SwingUtilities.getWindowAncestor(c);
        }
        return win;
    }

    public static void main(String[] args) {

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(3);
        frame.setSize(400, 300);
        frame.setVisible(true);
        new WindowMoveHandler().bindWindowMoveHanderTo(frame);
    }
}
